package com.qianying.utils;

import com.qianying.domain.*;
import com.qianying.mapper.MapMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.lang.model.element.NestingKind;
import java.util.*;

@Component
public class TreeDataHandle {

    @Autowired
    private MapMapper mapMapper;

    @Autowired
    private DataHelper dataHelper;

    @Transactional(rollbackFor = Exception.class)
    public void queryDataTree(TreeData treeNode, Map<String, Object> parentMapData)
    {
        QueryParam queryParam = new QueryParam();
        queryParam.setTableName(treeNode.getTableName());
        queryParam.setIsPage(false);

        if( treeNode.getOrderBy() != null )
        {
            queryParam.getOrderByNameList().add(treeNode.getOrderBy());
        }

        //驼峰转_
        dataHelper.mapCamelCaseToSnakeCaseSelf(treeNode.getWhereCondition());

        //查询条件
        QueryConditionItemMap queryCondition  = new QueryConditionItemMap();
        queryCondition.setWhereCondition(treeNode.getWhereCondition());
        queryParam.setWhereConditionList(Arrays.asList(queryCondition));

        //执行查询
        List<Map<String,Object>> selectDataList = mapMapper.select(queryParam);

        //_转换驼峰
        dataHelper.mapSnakeCaseToCamelCaseSelf(selectDataList);

        if(treeNode.getFilterQueryDataNameList() != null){

            for (Map<String,Object> selectDataItem : selectDataList){
                dataHelper.MapFilterSelf(selectDataItem,treeNode.getFilterQueryDataNameList());
            }
        }

        //添加父子关联
        if(parentMapData != null )
        {
            parentMapData.put(treeNode.getQueryDataName(), selectDataList.size() == 1 ? selectDataList.get(0): selectDataList );
        }

        //递归
        for (Map<String,Object> selectDataItemMap : selectDataList)
        {
            if( treeNode.getChildren() == null ) {
                continue;
            }

            for (TreeData treeNodeItem: treeNode.getChildren()) {

                if(treeNodeItem.getWhereCondition() == null)
                {
                    treeNodeItem.setWhereCondition(new HashMap<>() );
                }

                //判断是否有`号做大小区分的处理
                String fkName = treeNode.getTableName();

                if(fkName.startsWith("`")){
                    fkName = fkName.substring( 1, fkName.length() - 1 );
                }

                fkName += "_" + Dictionary.id;

                treeNodeItem.getWhereCondition().put( fkName, selectDataItemMap.get(Dictionary.id) );

                this.queryDataTree( treeNodeItem , selectDataItemMap) ;

            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDataTree(TreeData treeNode, Map<String,Object> treeNodeMap)
    {
        Map<String, Object> insertMap = treeNodeMap;

        //剔除非当前表的数据
        if(treeNode.getChildren() != null && treeNode.getChildren().size() > 0)
        {
            List<String> itemTableNameList = new ArrayList<>();

            for (TreeData treeDataItem : treeNode.getChildren()) {
                itemTableNameList.add(treeDataItem.getQueryDataName());
            }

            insertMap = dataHelper.mapGetKeyNotInList(treeNodeMap,itemTableNameList);
        }

        //转换_
        dataHelper.mapCamelCaseToSnakeCaseSelf(insertMap);

        //插入数据
        InsertParam insertParam = InsertParam.builder()
                .tableName(treeNode.getTableName())
                .insertData(insertMap)
                .build();

        mapMapper.insert(insertParam);

        //回填主键
        treeNodeMap.put(Dictionary.id,insertParam.getId());

        if(treeNode.getChildren() == null) {
            return;
        }

        //递归子表
        for ( TreeData subTreeDataItem : treeNode.getChildren() ) {

            Object subMapData = treeNodeMap.get(subTreeDataItem.getQueryDataName());

            if( subMapData == null  && !treeNode.isAutoOneRowToSubTable()  ) {
                continue;
            }

            List<Map<String,Object>> subTreeDataItemMapList = new ArrayList<>();

            if(subMapData  == null ) {

                //插入逻辑外键
                Map<String,Object> subQueryDataMap = new HashMap<>();
                subQueryDataMap.put( treeNode.getTableName() + "_" + Dictionary.id, insertParam.getId() );

                //插入数据
                subTreeDataItemMapList.add(subQueryDataMap);

                //回填数据
                treeNodeMap.put(subTreeDataItem.getQueryDataName(),subQueryDataMap);
            }
            else {
                if(subMapData instanceof  Map ) {

                    subTreeDataItemMapList.add((Map<String, Object>) subMapData );
                }
                else {

                    subTreeDataItemMapList = (List<Map<String,Object>> ) subMapData ;
                }

                //补入逻辑外键
                for(Map<String,Object> curTreeNodeMapItem : subTreeDataItemMapList) {

                    curTreeNodeMapItem.put( treeNode.getTableName() + "_" + Dictionary.id, insertParam.getId());
                }

            }

            insertDataTree(subTreeDataItem,subTreeDataItemMapList);

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDataTree(TreeData treeNode, List<Map<String,Object>> treeNodeMapList)
    {
        for (Map<String,Object> treeNodeMapItem : treeNodeMapList)
        {
            insertDataTree(treeNode,treeNodeMapItem);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDataTree( TreeData treeNode, Map<String,Object> treeNodeMap) {

        Map<String, Object> updateData = treeNodeMap;

        //剔除非当前表的数据
        if (treeNode.getChildren() != null && treeNode.getChildren().size() > 0) {
            List<String> itemTableNameList = new ArrayList<>();

            for (TreeData treeDataItem : treeNode.getChildren()) {
                itemTableNameList.add(treeDataItem.getQueryDataName());
            }

            updateData = dataHelper.mapGetKeyNotInList(treeNodeMap, itemTableNameList);
        }

        //转换_
        dataHelper.mapCamelCaseToSnakeCaseSelf(updateData);

        //获取id作为updatewhere条件
        if (updateData.get(Dictionary.id) == null) {
            return;
        }

        Map<String,Object> whereCondition = new HashMap<>();
        whereCondition.put(Dictionary.id,updateData.get(Dictionary.id));
        updateData = dataHelper.MapFilter(updateData,Arrays.asList(Dictionary.id));

        //update数据
        UpdateParam updateParam = UpdateParam.builder()
                .tableName(treeNode.getTableName())
                .whereData(whereCondition)
                .updateData(updateData)
                .build();

        mapMapper.update(updateParam);

        if(treeNode.getChildren() == null) {
            return;
        }

        //递归子表
        for ( TreeData subTreeDataItem : treeNode.getChildren() ) {

            Object subMapData = treeNodeMap.get(subTreeDataItem.getQueryDataName());

            if( subMapData == null   ) {
                continue;
            }

            List<Map<String,Object>> subTreeDataItemMapList = new ArrayList<>();

            if(subMapData instanceof  Map ) {

                subTreeDataItemMapList.add((Map<String, Object>) subMapData );
            }
            else {

                subTreeDataItemMapList = (List<Map<String,Object>> ) subMapData ;
            }

            updateDataTree(subTreeDataItem,subTreeDataItemMapList);

        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDataTree( TreeData treeNode, List<Map<String,Object>> treeNodeMapList)
    {
        for (Map<String,Object> treeNodeMapItem : treeNodeMapList)
        {
            updateDataTree(treeNode,treeNodeMapItem);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveDataTree( TreeData treeNode, Map<String,Object> treeNodeMap) {

        Map<String, Object> dataMap = treeNodeMap;

        //剔除子表数据
        if(treeNode.getChildren() != null && treeNode.getChildren().size() > 0)
        {
            List<String> itemTableNameList = new ArrayList<>();

            for (TreeData treeDataItem : treeNode.getChildren()) {
                itemTableNameList.add(treeDataItem.getQueryDataName());
            }

            dataMap = dataHelper.mapGetKeyNotInList(treeNodeMap,itemTableNameList);
        }

        //驼峰转下划线Map
        dataHelper.mapCamelCaseToSnakeCaseSelf(dataMap);

        boolean isInsert = treeNodeMap.get(Dictionary.id) == null ;

        if( isInsert ) {

            //插入处理
            InsertParam insertParam = InsertParam.builder()
                    .tableName(treeNode.getTableName())
                    .insertData(dataMap)
                    .build();

            mapMapper.insert(insertParam);

            //回填主键
            treeNodeMap.put(Dictionary.id,insertParam.getId());

        }
        else {

            //update 处理
            Map<String,Object> whereUpdateMap = new HashMap<>();
            whereUpdateMap.put( Dictionary.id, dataMap.get(Dictionary.id) );

            dataMap = dataHelper.MapFilter(dataMap, Arrays.asList( Dictionary.id ) );

            if(dataMap.size() > 0 )
            {
                UpdateParam updateParam = UpdateParam.builder()
                        .tableName(treeNode.getTableName())
                        .updateData(dataMap)
                        .whereData(whereUpdateMap)
                        .build();

                mapMapper.update(updateParam);
            }

        }

        if(treeNode.getChildren() == null) {
            return;
        }

        //递归子表
        for ( TreeData treeDataItem : treeNode.getChildren() ) {

            Object treeDataObj = treeNodeMap.get( treeDataItem.getQueryDataName() );

            if( treeDataObj == null   ) {
                continue;
            }

            List<Map<String,Object>> treeDataItemMapList = new ArrayList<>();

            if( treeDataObj instanceof  Map ) {

                treeDataItemMapList.add((Map<String, Object>) treeDataObj );
            }
            else {

                treeDataItemMapList = (List<Map<String,Object>> ) treeDataObj ;
            }

            //判断子表是insert 还是 update ,如果是insert 则添加主表id到子表做逻辑外键
            for(Map<String,Object> curTreeNodeMapItem : treeDataItemMapList) {

                if(curTreeNodeMapItem.get(Dictionary.id) == null)
                {

                    //判断是否有`号做大小区分的处理
                    String fkName = treeNode.getTableName();

                    if(fkName.startsWith("`")){
                        fkName = fkName.substring( 1, fkName.length() - 1 );
                    }

                    fkName += "_" + Dictionary.id;

                    curTreeNodeMapItem.put( fkName , treeNodeMap.get(Dictionary.id) );
                }
            }

            saveDataTree(treeDataItem,treeDataItemMapList);

        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void saveDataTree( TreeData treeNode, List<Map<String,Object>> treeNodeMapList) {

        for (Map<String,Object> treeNodeMapItem : treeNodeMapList)
        {
            saveDataTree(treeNode,treeNodeMapItem);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteDataTree(TreeData treeNode, String fieldName,long fieldValue) {

        Map<String,Object> condition = new HashMap<>();
        condition.put(fieldName,fieldValue);

        if(fieldName == Dictionary.id){

            DeleteParam deleteParam = DeleteParam.builder()
                    .tableName(treeNode.getTableName())
                    .whereData(condition)
                    .build();

            mapMapper.delete(deleteParam);

        }
        else{

            QueryParam queryParam = new QueryParam();
            queryParam.setTableName(treeNode.getTableName());
            queryParam.setIsPage(false);
            queryParam.setSelectName(Dictionary.id);
            queryParam.setWhereConditionList(Arrays.asList(
                    QueryConditionItemMap.builder()
                            .whereCondition(condition)
                            .build()
            ));

            //执行查询
            List<Map<String,Object>> selectDataList = mapMapper.select(queryParam);

            for (Map<String,Object> item : selectDataList){

                DeleteParam deleteParam = DeleteParam.builder()
                        .tableName(treeNode.getTableName())
                        .whereData(item)
                        .build();

                mapMapper.delete(deleteParam);

            }

        }

        if(treeNode.getChildren() == null ){
            return;
        }

        //递归子表
        for ( TreeData subTreeDataItem : treeNode.getChildren() ) {

            //判断是否有`号做大小区分的处理
            String fkName = treeNode.getTableName();

            if(fkName.startsWith("`")){
                fkName = fkName.substring( 1, fkName.length() - 1 );
            }

            fkName += "_" + Dictionary.id;

            deleteDataTree(subTreeDataItem,fkName,fieldValue);

        }

    }

//    @Transactional(rollbackFor = Exception.class)
//    public void deleteDataTree(TreeData treeNode){
//
//        if(treeNode.getWhereCondition().get( Dictionary.id ) != null ) {
//
//            DeleteParam deleteParam = DeleteParam.builder()
//                    .tableName(treeNode.getTableName())
//                    .whereData(treeNode.getWhereCondition())
//                    .build();
//
//            mapMapper.delete(deleteParam);
//        }
//        else {
//
//            QueryParam queryParam = new QueryParam();
//            queryParam.setTableName(treeNode.getTableName());
//            queryParam.setIsPage(false);
//            queryParam.setSelectName(Dictionary.id);
//            //查询条件
//            QueryConditionItemMap queryCondition  = new QueryConditionItemMap();
//            queryCondition.setWhereCondition(treeNode.getWhereCondition());
//            queryParam.setWhereConditionList(Arrays.asList(queryCondition));
//
//            //执行查询
//            List<Map<String,Object>> selectDataList = mapMapper.select(queryParam);
//
//            for (Map<String,Object> item : selectDataList){
//
//                DeleteParam deleteParam = DeleteParam.builder()
//                        .tableName(treeNode.getTableName())
//                        .whereData(item)
//                        .build();
//
//                mapMapper.delete(deleteParam);
//
//            }
//
//        }
//
//        if(treeNode.getChildren() == null ){
//            return;
//        }
//
//        //递归子表
//        for ( TreeData subTreeDataItem : treeNode.getChildren() ) {
//
//            //判断是否有`号做大小区分的处理
//            String fkName = treeNode.getTableName();
//
//            if(fkName.startsWith("`")){
//                fkName = fkName.substring( 1, fkName.length() - 1 );
//            }
//
//            fkName += "_" + Dictionary.id;
//
//            Map<String,Object> fkConditionMap = new HashMap<>();
//
//            fkConditionMap.put(fkName,treeNode.getWhereCondition().get( Dictionary.id ) );
//
//            subTreeDataItem.setWhereCondition(fkConditionMap);
//
//            deleteDataTree(subTreeDataItem);
//
//        }
//
//    }

}